import { Injectable, Logger } from '@nestjs/common';
import axios, { AxiosResponse } from 'axios';
import { Response } from 'express';
import { Readable } from 'stream';
import { createInterface } from 'readline';
import { ConfigService } from '@nestjs/config';
import { InfoService } from '../info/info.service';
import { RecordsService } from '../records/records.service';
import { SessionService } from '../session/session.service';
import { SpectrumService } from '../spectrum/spectrum.service';
import { AiService } from '../ai/ai.service';
import { SmsService } from '../sms/sms.service';
import { AlarmService } from '../alarm/alarm.service';
import OpenAI from 'openai';

@Injectable()
export class AliyunChatService {
  private readonly apiParentKey = 'sk-d3b8228696f642cb9338469f66d84555';
  private readonly apiKey = 'lm-7F7at2+J+7Szneo7w0eTBA==';
  private readonly serviceName = 'aca-chat-send-sse';
  private readonly url = 'https://nlp.aliyuncs.com/v2/api/chat/send';
  private openai: OpenAI;
  private model = 'qwen-plus'; // 可根据需要替换为其他模型
  private region: 'cn-beijing' | 'sg' = 'cn-beijing';

  private logger = new Logger(AliyunChatService.name);
  constructor(
    private readonly infoService: InfoService,
    private readonly recordsService: RecordsService,
    private readonly sessionService: SessionService,
    private readonly aiService: AiService,
    private readonly alarmService: AlarmService,
    private readonly smsService: SmsService,
  ) {
    // 根据地域选择不同的baseURL
    const baseURL = this.region === 'cn-beijing' ? 'https://dashscope.aliyuncs.com/compatible-mode/v1' : 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1';
    this.openai = new OpenAI({
      apiKey: this.apiParentKey,
      baseURL: baseURL,
    });
  }

  /**
   * 发送 SSE 聊天消息（适配 GET 请求，参数从 Query 中获取）
   * @param message 用户消息（字符串）
   * @param sessionId 用户ID（数字）
   * @param res 响应对象（用于流式输出）
   */
  async sendSSEChatMessage(message: string, sessionId: string, res: Response): Promise<void> {
    let isClosed = false;
    const safeEnd = () => {
      if (!isClosed) {
        isClosed = true;
        res.end();
      }
    };

    // 修复1：适配上游非标准SSE格式（直接返回JSON字符串，无data:前缀）
    const parseSSEChunk = (chunk: Buffer): string => {
      // 直接转换为字符串并清理空白字符
      return chunk.toString('utf-8').trim();
    };

    try {
      // 1. 校验会话
      const sessionInfo = await this.sessionService.findOneById(Number(sessionId));
      if (!sessionInfo) {
        res.status(404).write(`event: error\ndata: ${JSON.stringify({ message: '会话不存在' })}\n\n`);
        safeEnd();
        return;
      }
      const userId = sessionInfo.userId;

      await this.analyzeWarningThreshold(Number(sessionId), message);

      // 2. 获取孩子信息
      const childInfo = await this.infoService.findOne(userId);
      if (!childInfo?.data) {
        res.status(404).write(`event: error\ndata: ${JSON.stringify({ message: '未找到孩子信息' })}\n\n`);
        safeEnd();
        return;
      }

      // 3. 构建系统提示词
      const systemPrompt: string = `你现在需要了解一个孩子的基本情况，以便更好地与他/她互动。以下是孩子相关信息：
              - 孩子昵称：${childInfo.data.childNickname}
              - 孩子性别：${childInfo.data.childGender === '1' ? '男' : '女'}
              - 性格特点：${childInfo.data.personality || '（若家长未填写则为空）'}
              - 兴趣爱好：${childInfo.data.hobbies || '（若家长未填写则为空）'}
              - 交流诉求：${childInfo.data.communicationAppeal || '（若家长未填写则为空）'}
              请基于以上信息，建立对该孩子的认知和了解，在与他/她互动时，可以充分考虑这些因素，以贴合孩子特点的方式进行交流。`;

      // 4. 配置请求头
      const headers = {
        'Content-Type': 'application/json',
        'X-AcA-DataInspection': 'enable',
        'x-fag-servicename': this.serviceName,
        'x-fag-appcode': 'aca',
        'X-AcA-SSE': 'enable',
        Authorization: `Bearer ${this.apiKey}`,
      };

      // 5. 构建请求体
      const payload = {
        input: {
          messages: [
            { role: 'system', content: systemPrompt },
            { role: 'user', content: message },
          ],
          aca: {
            botProfile: { characterId: 'fb3b03077eb34544a85dcb13bf94d4e4' },
            userProfile: { userId },
            scenario: { description: '' },
            context: { useChatHistory: true },
          },
        },
      };

      // 6. 调用上游SSE服务
      const response = await axios.post(this.url, payload, {
        headers,
        responseType: 'stream',
      });

      // 7. 配置SSE响应头
      res.setHeader('Content-Type', 'text/event-stream');
      res.setHeader('Cache-Control', 'no-cache, no-store');
      res.setHeader('Connection', 'keep-alive');
      res.setHeader('X-Accel-Buffering', 'no');
      res.setHeader('Retry-After', '3000');
      res.flushHeaders();

      // 8. 流处理核心逻辑（修复：适配上游JSON格式，修正content提取路径）
      const stream = response.data;
      let lastContent = ''; // 用于计算增量内容
      let fullAiReply = ''; // 累计完整回复
      let buffer = ''; // 用于拼接不完整的数据块

      // 处理上游数据流
      stream.on('data', (chunk: Buffer) => {
        if (isClosed) return;

        try {
          // 将当前块添加到缓冲区
          buffer += chunk.toString('utf-8');

          // 按SSE标准分隔符（双换行）拆分完整的消息
          const aiContents = buffer.split('\n\n');

          // 保留最后一个可能不完整的消息在缓冲区中
          buffer = aiContents.pop() || '';

          // 处理所有完整的消息
          for (const aiContent of aiContents) {
            if (!aiContent.trim()) continue;

            console.log('处理SSE消息:', aiContent);

            // 解析SSE事件格式
            const lines = aiContent.split('\n');
            let eventData = '';

            for (const line of lines) {
              if (line.startsWith('data:')) {
                eventData += line.slice(5).trim();
              }
              // 可以根据需要处理其他SSE字段如event:、id:等
            }

            if (!eventData) {
              // 非data事件直接透传
              res.write(`${aiContent}\n\n`);
              continue;
            }

            // 修复可能的格式问题
            eventData = eventData.replace(/\s+/g, ' ');

            try {
              // 解析JSON数据
              const parsedData = JSON.parse(eventData) as {
                choices?: Array<{
                  messages?: Array<{
                    content?: string;
                  }>;
                }>;
                stop?: boolean;
              };

              // 提取content字段
              const currentContent = parsedData.choices?.[0]?.messages?.[0]?.content || '';
              if (currentContent) {
                // 计算新增内容
                const newContent = currentContent.slice(lastContent.length);
                if (newContent) {
                  res.write(`data: ${JSON.stringify({ content: newContent })}\n\n`);
                  lastContent = currentContent;
                  fullAiReply += newContent;
                }
              }

              // 处理结束信号
              if (parsedData.stop === true) {
                // 保存聊天记录
                if (fullAiReply.trim()) {
                  (async () => {
                    try {
                      await this.recordsService.create({
                        sessionId,
                        content: message,
                        aiReply: fullAiReply,
                      });
                    } catch (err) {
                      console.error('保存聊天记录失败:', err);
                    }
                  })();
                }
                res.write(
                  `event: end\ndata: ${JSON.stringify({
                    message: '对话结束',
                    fullReply: fullAiReply,
                  })}\n\n`,
                );
                safeEnd();
                return;
              }
            } catch (jsonError) {
              console.error('JSON解析失败:', jsonError);
              console.error('原始数据:', eventData);
              // 对于解析失败的数据，尝试提取有效内容或直接透传
              res.write(`data: ${JSON.stringify({ content: eventData, raw: true })}\n\n`);
            }
          }
        } catch (error) {
          console.error('流数据处理异常:', error);
          res.write(
            `event: error\ndata: ${JSON.stringify({
              message: '数据处理异常，请重试',
              error: error.message,
            })}\n\n`,
          );
        }
      });

      // 9. 上游流结束处理
      stream.on('end', async () => {
        if (isClosed) return;

        // 保存聊天记录
        if (fullAiReply.trim()) {
          try {
            await this.recordsService.create({
              sessionId,
              content: message,
              aiReply: fullAiReply,
            });
          } catch (err) {
            console.error('保存聊天记录失败:', err);
          }
        }

        // 发送结束事件
        res.write('event: end\ndata: {"complete": true, "replyLength": 1}\n\n');
        safeEnd();
      });

      // 10. 上游流错误处理
      stream.on('error', (error: Error) => {
        console.error('上游流错误:', error.message);
        if (!isClosed) {
          res.write(`event: error\ndata: ${JSON.stringify({ message: '上游服务连接异常' })}\n\n`);
          safeEnd();
        }
      });

      // 11. 客户端断开连接处理
      res.on('close', () => {
        isClosed = true;
        stream.destroy();
        console.log(`客户端${userId}断开SSE连接，已清理资源`);
      });

      // 12. 客户端错误处理
      res.on('error', (error: Error) => {
        console.error('客户端响应错误:', error.message);
        isClosed = true;
        stream.destroy();
      });
    } catch (error) {
      console.error('发送SSE消息失败:', error.response?.status, error.message);
      if (!isClosed) {
        const statusCode = error.response?.status || 500;
        const errorMsg = error.response?.data?.message || '服务异常，请稍后再试';
        res.status(statusCode).write(`event: error\ndata: ${JSON.stringify({ message: errorMsg })}\n\n`);
        safeEnd();
      }
    }
  }

  async sendChatMessage(message: string, userId: number): Promise<Readable> {
    const childInfo = await this.infoService.findOne(userId);
    const text: string = `你现在需要了解一个孩子的基本情况，以便更好地与他/她互动。以下是孩子相关信息：
              - 孩子昵称：${childInfo.data.childNickname}
              - 孩子性别：${childInfo.data.childGender === '1' ? '男' : '女'}
              - 性格特点：${childInfo.data.personality || '（若家长未填写则为空）'}
              - 兴趣爱好：${childInfo.data.hobbies || '（若家长未填写则为空）'}
              - 交流诉求：${childInfo.data.communicationAppeal || '（若家长未填写则为空）'}
              请基于以上信息，建立对该孩子的认知和了解，在与他/她互动时，可以充分考虑这些因素，以贴合孩子特点的方式进行交流。`;

    console.log(`孩子的基本信息: ${text}`);

    const headers = {
      'Content-Type': 'application/json',
      'X-AcA-DataInspection': 'enable',
      'x-fag-servicename': this.serviceName,
      'x-fag-appcode': 'aca',
      'X-AcA-SSE': 'enable',
      Authorization: `Bearer ${this.apiKey}`,
    };

    const payload = {
      input: {
        messages: [
          { role: 'user', content: message },
          { role: 'system', content: text },
        ],
        aca: {
          botProfile: {
            characterId: 'fb3b03077eb34544a85dcb13bf94d4e4',
          },
          userProfile: {
            userId: userId,
          },
          scenario: {
            description: '',
          },
          context: {
            useChatHistory: true,
          },
        },
      },
    };

    try {
      // 保持axios响应类型为stream，确保流式数据正确传递
      const response = await axios.post(this.url, payload, {
        headers,
        responseType: 'stream',
      });

      const stream = new Readable({ read() {} });
      const rl = createInterface({
        input: response.data,
        crlfDelay: Infinity, // 处理所有换行符格式
      });

      // 逐行推送SSE数据到自定义流
      rl.on('line', (line) => {
        stream.push(line + '\n');
      });

      // 流结束标识
      rl.on('close', () => {
        stream.push(null);
      });

      // 传递错误事件
      rl.on('error', (error) => {
        stream.emit('error', error);
      });

      return stream;
    } catch (error) {
      console.error('阿里云Chat请求失败:', error.response?.status, error.response?.data);
      throw error;
    }
  }

  // async sendParentChatMessage(message: string, userId: number): Promise<Readable> {
  //   const headers = {
  //     'Content-Type': 'application/json',
  //     'X-AcA-DataInspection': 'enable',
  //     'x-fag-servicename': this.serviceName,
  //     'x-fag-appcode': 'aca',
  //     'X-AcA-SSE': 'enable',
  //     Authorization: `Bearer ${this.apiKey}`,
  //   };
  //
  //   const payload = {
  //     input: {
  //       messages: [{ role: 'user', content: message }],
  //       aca: {
  //         botProfile: {
  //           characterId: 'c2680ff3461d47c889e74d3800061e1a',
  //         },
  //         userProfile: {
  //           userId: userId,
  //         },
  //         scenario: {
  //           description: '',
  //         },
  //         context: {
  //           useChatHistory: true,
  //         },
  //       },
  //     },
  //   };
  //
  //   try {
  //     // 保持axios响应类型为stream，确保流式数据正确传递
  //     const response = await axios.post(this.url, payload, {
  //       headers,
  //       responseType: 'stream',
  //     });
  //
  //     const stream = new Readable({ read() {} });
  //     const rl = createInterface({
  //       input: response.data,
  //       crlfDelay: Infinity, // 处理所有换行符格式
  //     });
  //
  //     // 逐行推送SSE数据到自定义流
  //     rl.on('line', (line) => {
  //       stream.push(line + '\n');
  //     });
  //
  //     // 流结束标识
  //     rl.on('close', () => {
  //       stream.push(null);
  //     });
  //
  //     // 传递错误事件
  //     rl.on('error', (error) => {
  //       stream.emit('error', error);
  //     });
  //
  //     return stream;
  //   } catch (error) {
  //     console.error('阿里云Chat请求失败:', error.response?.status, error.response?.data);
  //     throw error;
  //   }
  // }

  // async sendParentChatMessage(message: string, sessionId: number): Promise<Readable> {
  //   const stream = new Readable({ read() {} });
  //
  //   try {
  //     //  获取上下文
  //     const context = await this.recordsService.findSessionContext(sessionId);
  //
  //     context.push({ role: 'user', content: message });
  //
  //     // 创建流式对话请求
  //     const completionStream = await this.openai.chat.completions.create({
  //       model: this.model,
  //       messages: context,
  //       stream: true, // 启用流式响应
  //       // 可以添加其他参数如temperature等
  //       // temperature: 0.7,
  //     });
  //
  //     // 处理流式响应
  //     (async () => {
  //       try {
  //         for await (const chunk of completionStream) {
  //           // 提取内容片段
  //           const content = chunk.choices[0]?.delta?.content;
  //           if (content) {
  //             // 推送内容到自定义流
  //             stream.push(content);
  //           }
  //         }
  //       } catch (error) {
  //         stream.emit('error', error);
  //       } finally {
  //         // 流结束标识
  //         stream.push(null);
  //       }
  //     })();
  //
  //     return stream;
  //   } catch (error) {
  //     console.error('阿里云Chat请求失败:', error);
  //     // 立即触发错误事件并结束流
  //     stream.emit('error', error);
  //     stream.push(null);
  //     return stream;
  //   }
  // }

  async sendParentChatMessage(message: string, sessionId: number): Promise<Readable> {
    //  获取上下文
    const context = await this.recordsService.findSessionContext(sessionId);

    context.push({ role: 'user', content: message });

    console.log('context', context);
    const headers = {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${this.apiParentKey}`, // 这里使用DashScope的API密钥
    };

    // 适配DashScope API的请求体格式
    const payload = {
      model: 'qwen-plus', // 指定使用的模型
      messages: context,
      stream: true, // 启用流式响应
    };

    try {
      // 发送请求到新的API端点，保持流式响应设置
      const response = await axios.post('https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions', payload, {
        headers,
        responseType: 'stream',
      });

      // 创建自定义可读流用于传递数据
      const stream = new Readable({ read() {} });
      const rl = createInterface({
        input: response.data,
        crlfDelay: Infinity, // 处理所有换行符格式
      });

      // 逐行处理SSE数据（DashScope的流式响应为JSON Lines格式）
      rl.on('line', (line) => {
        // 过滤掉空行和SSE事件标识行
        if (line && line !== 'data: [DONE]') {
          stream.push(line + '\n');
          console.log('line', line);
        }
      });

      // 流结束时关闭自定义流
      rl.on('close', () => {
        stream.push(null);
      });

      // 错误处理
      rl.on('error', (error) => {
        stream.emit('error', error);
      });

      return stream;
    } catch (error) {
      console.error('DashScope API请求失败:', error.response?.status, error.response?.data);
      throw error;
    }
  }

  async analyzeWarningThreshold(sessionId: number, content: string) {
    try {
      const s = await this.aiService.askQuestion(
        content,
        '你是一个心理对话监测助手。  \n' +
          '输入为【用户单轮对话文本】。  \n' +
          '\n' +
          '任务：  \n' +
          '1. 如果对话出现**严重负面或危险言语**（如“想结束自己的生命”“我要自杀”“我要杀人”等），输出红色警报=2，并在解释中说明其存在极高风险（例如自杀、自残、暴力等），严重危及生命安全。  \n' +
          '2. 如果对话出现**强烈的回避、否定、自我贬低、绝望**等倾向（如“不想活了”“不想面对任何人”“我很没用”），输出橙色警报=3，并在解释中说明其表现出严重的心理困境或绝望倾向。  \n' +
          '3. 如果对话只是**轻度的情绪低落、抱怨、焦虑**（如“很烦”“有点焦虑”“不开心”），输出蓝色警报=1，并在解释中说明其表现为轻度的情绪困扰。  \n' +
          '4. 如果未检测到任何负面或危险内容（如“我去上学了”“我吃饭了”），则输出=0，表示没有风险、不需要预警。  \n' +
          '\n' +
          '输出格式（只输出纯 JSON，不要包含任何 Markdown 格式或额外解释）：  \n' +
          '{\n' +
          '  "emotion_flow": "0/1/2/3",\n' +
          '  "alarm_trigger_content": "原始对话内容和触发预警的原因解释"\n' +
          '}\n' +
          '\n' +
          '【用户单轮对话文本】：<<<在这里粘贴文本>>>',
      );

      const parsed = AliyunChatService.parse(s);
      if (parsed.emotion_flow > 0) {
        const sessionInfo = await this.sessionService.findSessionInfo(sessionId);
        const userInfo = sessionInfo[0];
        const { phonenumber, userId, parentId } = userInfo;

        await this.alarmService.create({
          userId: parentId,
          childId: userId,
          alarmType: parsed.emotion_flow,
          alarmTriggerContent: parsed.alarm_trigger_content,
        });

        await this.smsService.sendSms(String(phonenumber), '上海智影慧心数字科技', 'SMS_493690377', '');
      }
    } catch (error) {
      this.logger.error('预警分析失败:', error);
    }
  }

  static parse(content: string): any {
    try {
      return JSON.parse(content);
    } catch (error) {
      throw new Error('Invalid JSON format in content');
    }
  }
}
